<?php

namespace app\api\controller\util;

use think\Controller;
use think\Response;
use think\facade\Request;

/**
 * Class File
 * @package app\api\controller\util
 *
 * 文件上传需要验证Token，所以继承ApiCommon
 */
class File extends Controller {

    public function _initialize() {
        parent::_initialize();
        header('Access-Control-Allow-Origin: *');
        header('Access-Control-Allow-Credentials: true');//头部是否包含cookie
        header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
        header("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, token, user-session-id, user-key, sign");

        if (Request::instance()->isOptions())
            exit();
        // upload没有传module或type参数直接返回非法请求
        $api = $_SERVER['PHP_SELF'];
        if ($api === '/index.php/FileUpload' && (!input('?get.module') || !input('?get.type')))
            api_error('非法请求')->send();
    }

    /**图片裁剪*/
    function base64_image_content($base64_image_content,$path){
        //匹配出图片的格式
        if (preg_match('/^(data:\s*image\/(\w+);base64,)/', $base64_image_content, $result)){
            $type = $result[2];
            $new_file = $path."/".date('Ymd',time());
            $path_arr = explode('/',$new_file);
//            dump($path_arr);
//            return ;
            for($i=0;$i<count($path_arr);$i++){
                static $dir;//只初始化一次，保留上次调用的值
                $dir .= $path_arr[$i].'/';//i=0 ./ i=1 ./a i=2 ./a/b .....
                //echo $dir,'<br/>';
                if(!is_dir($dir)){//过滤下 如果已经是目录就不创建 比如 ./
                    mkdir($dir, 0777);
                }
            }
//            if(!file_exists($new_file)){
//                //检查是否有该文件夹，如果没有就创建，并给予最高权限
//                mkdir($new_file, 0777);
//            }
            $new_file = $new_file.'/'.time().".{$type}";
            if (file_put_contents($new_file, base64_decode(str_replace($result[1], '', $base64_image_content)))){
                return '/'.$new_file;
            }else{
                return false;
            }
        }else{
            return false;
        }
    }
    /**图片裁剪， $blur：模糊图*/
    public function uploadBase64($module, $blur){
        $paths = config('file_upload_path');
//                debugres($paths);
        if (!isset($paths[$module]))
            return api_error('非法请求1');
        $files = input('param.files');
//        return $files;
//        return 'bbb';
        $files = $this->base64_image_content($files,"uploads/".$module);

        $oss_path = str_replace('/uploads','',$files);
        $base_path = config('file_upload_path_base').$oss_path;
        $oss_path=ltrim($oss_path,'/');


        //图片模糊图
        if ($module=='DesignBuy' && $blur == true){
            $img = new \service\util\Image();
            $arr = explode('/',$oss_path);
            $arr_last = array_pop($arr);
            $name_arr = explode('.',$arr_last); //4ebb765a7f49bf09d57644ac2980949a.jpg 分成两部分
            $name = md5($name_arr[0]);
            $ext = $name_arr[1];
            $img_name = $name.'.'.$ext;
            $blur_oss_path = $arr[0].'/'.$arr[1].'/'.$img_name;
            $blurFactor = 7;
            ini_set("memory_limit", "10000M");
//                \think\Image::open($file) 在苹果系统和linux系统找不到临时文件。不知道是什么问题。
//            debugres($base_path);
            $image = \think\Image::open($base_path);
            $image_width = $image->width();
            $image_height = $image->height();
            if($image_width*$image_height<250000){
                $blurFactor = 4;
            }else if($image_width*$image_height>250000 && $image_width*$image_height<1000000){
                $blurFactor = 5;
            }else if($image_width*$image_height>1000000 && $image_width*$image_height<25000000){
                $blurFactor = 6;
            }else{
                $blurFactor = 7;
            }
            //生成模糊图片。
            $blur_base_path = $img->gaussian_blur($base_path,null,$img_name,$blurFactor);
            $info['blur_path'] = './'.$blur_oss_path;
            \service\util\File::oss_upload($blur_oss_path,$blur_base_path,$module);

        }

        $res = \service\util\File::oss_upload($oss_path,$base_path,$module);
        if($res){
            $info['is_success'] = true;
            $info['file_path'] = './'.$oss_path;
            return  $info;
        }else{
            $info['is_success'] = false;
            $info['error_msg'] = '上传失败';
            return  $info;
        }

    }

    /**
     * 远程链接图片剪切上传
     * 要去除./，格式为Information/20181108/983ffee6e22c19057eda343d2cc5c9db.jpg或更简洁
     *前端请求地址: http://www.xxx.com/CutFileUpload?module=demo&tmp_img=./Information/20181108/983ffee6e22c19057eda343d2cc5c9db.jpg&dst_w&dst_h=8&start_x=1&start_y=2
     *
     */
    public function upload_cut_old($module, $tmp_img, $dst_w, $dst_h, $start_x=0, $start_y=0) {
        //Information/20181108/983ffee6e22c19057eda343d2cc5c9db.jpg
        $tmp_img_arr = explode('./',$tmp_img);
        if(count($tmp_img_arr) == 2){
            $tmp_img = $tmp_img_arr[1];
        }
        if($module == 'DesignBuy'){
            $bucket=config('aliyun_oss_design')['Bucket'];
            $imgstream_url = config('aliyun_oss_design')['httpEndpoint'].$tmp_img;
        }else{
            $bucket=config('aliyun_oss')['Bucket'];
            $imgstream_url = config('aliyun_oss')['httpEndpoint'].$tmp_img;
        }
        $ossClient = \service\util\File::new_oss($module);

        try{
            $res = $ossClient->doesObjectExist($bucket, $tmp_img);
        } catch(\OSS\Core\OssException $e) {
            return api_error($e->getMessage());
        }
        if(!$res) return api_error('图片路径有误');

        //获取临时文件图片
        $imgstream = file_get_contents($imgstream_url);
        if(preg_match("/".chr(0x21).chr(0xff).chr(0x0b).'NETSCAPE2.0'."/",$imgstream)){//判断是否gif
        }else{
        }
        $im = imagecreatefromstring($imgstream);
        $x = imagesx($im);//获取图片的宽
        $y = imagesy($im);//获取图片的高
        if($x>$y){//图片宽大于高
            $sx = abs(($y-$x)/2);
            $sy = 0;
            $thumbw = $y;
            $thumbh = $y;
        } else {//图片高大于等于宽
            $sy = abs(($x-$y)/2.5);
            $sx = 0;
            $thumbw = $x;
            $thumbh = $x;
        }

        if(function_exists("imagecreatetruecolor")) {
            $dim = imagecreatetruecolor($dst_w, $dst_h); // 创建目标图gd2
        } else {
            $dim = imagecreate($dst_w, $dst_h); // 创建目标图gd1
        }

//        imageCopyreSampled ($dim,$im,$start_x,$start_y,0,0,$dst_w,$dst_h,$thumbw,$thumbh);;
        imagecopy($dim,$im,0,0,$start_x,$start_y,$dst_w,$dst_h);
        // 图片保存
        $ext=pathinfo($tmp_img,PATHINFO_EXTENSION);

        $rand_name=md5(mt_rand().time()).".".$ext;
        switch($ext){
            case 'jpg':
            case 'jpeg':
            case 'jpe':
                imagejpeg($dim,$rand_name);
                break;
            case 'png':
                imagepng($dim,$rand_name);
                break;
            case 'gif':
                imagegif($dim,$rand_name);
                break;
            case 'bmp':
            case 'wbmp':
                imagewbmp($dim,$rand_name);
                break;
        }
//        imagedestroy($dim);
        $oss_path = $module.'/'.date('Ymd').'/'.$rand_name;
        $res = \service\util\File::oss_upload($oss_path,$rand_name,$module);
        if($res){
            $data =  [
                'code' => 0,
                'is_success' => true,
                'file_path' => $oss_path
            ];
//            $ossClient->deleteObject($bucket, $tmp_img);
        }else{
            $data = [
                'code' => 0,
                'is_success' => false,
                'file_path' => ''
            ];
        }
        return [$data];
    }

    public function upload_cut($module, $tmp_img, $dst_w, $dst_h, $start_x=0, $start_y=0,$blur=false) {
        $tmp_img_arr = explode('./',$tmp_img);
        if(count($tmp_img_arr) == 2){
            $tmp_img = $tmp_img_arr[1];
        }
        if($module == 'DesignBuy'){
            $bucket=config('aliyun_oss_design')['Bucket'];
            $imgstream_url = config('aliyun_oss_design')['httpEndpoint'].$tmp_img;
        }else{
            $bucket=config('aliyun_oss')['Bucket'];
            $imgstream_url = config('aliyun_oss')['httpEndpoint'].$tmp_img;
        }
        $ossClient = \service\util\File::new_oss($module);
        try{
            $res = $ossClient->doesObjectExist($bucket, $tmp_img);
        } catch(\OSS\Core\OssException $e) {
            return api_error($e->getMessage());
        }
        if(!$res) return api_error('图片路径有误');
        $ext=pathinfo($tmp_img,PATHINFO_EXTENSION);
        $imgstream = file_get_contents($imgstream_url);
        if($ext == 'gif'){//判断是否gif
            downLoadPic($imgstream_url);
            $pic_name = pathinfo($imgstream_url, PATHINFO_BASENAME);
            $new_pic_name = 'new_pic_name'.$pic_name;
            $local_url = PUBLIC_PATH.$pic_name;
            $new_local_url = PUBLIC_PATH.$new_pic_name;

            $gr = new \service\util\GIFSize();
            $gr->temp_dir = PUBLIC_PATH;
            $gr->resize($local_url,$new_local_url,$dst_w,$dst_h,$start_x,$start_y);
            $oss_path = $module.'/'.date('Ymd').'/'.$new_pic_name;

            if($blur==true){  //模糊图
                $blur_img_url = $this->blur_img($oss_path,$new_local_url,$module);
            }
            $res = \service\util\File::oss_upload($oss_path,$new_local_url,$module);
            if(file_exists($local_url)) unlink($local_url);
            if(file_exists($new_local_url)) unlink($new_local_url);
        }else{
            $im = imagecreatefromstring($imgstream);

            if(function_exists("imagecreatetruecolor")) {
                $dim = imagecreatetruecolor($dst_w, $dst_h); // 创建目标图gd2
            } else {
                $dim = imagecreate($dst_w, $dst_h); // 创建目标图gd1
            }
            imagecopy($dim,$im,0,0,$start_x,$start_y,$dst_w,$dst_h);

            // 图片保存
            $rand_name=md5(mt_rand().time()).".".$ext;
            switch($ext){
                case 'jpg':
                case 'jpeg':
                case 'jpe':
                    imagejpeg($dim,$rand_name);
                    break;
                case 'png':
                    imagepng($dim,$rand_name);
                    break;
                case 'gif':
                    imagegif($dim,$rand_name);
                    break;
                case 'bmp':
                case 'wbmp':
                    imagewbmp($dim,$rand_name);
                    break;
            }
            imagedestroy($dim);
            $oss_path = $module.'/'.date('Ymd').'/'.$rand_name;
            if($blur==true){  //模糊图
                $blur_img_url = $this->blur_img($oss_path,$rand_name,$module);
            }
            $res = \service\util\File::oss_upload($oss_path,$rand_name,$module);
        }

        if($res){
            if($blur==true){  //模糊图
                $data =  [
                    'code' => 0,
                    'is_success' => true,
                    'file_path' => $oss_path,
                    'blur_path'=> $blur_img_url
                ];
            }else{
                $data =  [
                    'code' => 0,
                    'is_success' => true,
                    'file_path' => $oss_path,
                ];
            }
            $ossClient->deleteObject($bucket, $tmp_img);
        }else{
            $data = [
                'code' => 1,
                'is_success' => false,
                'file_path' => ''
            ];
        }
        return [$data];
    }

    /**
     * 模糊图
     */
    public function blur_img($oss_path,$base_path,$module){
        $img = new \service\util\Image();
        $arr = explode('/',$oss_path);
        $arr_last = array_pop($arr);
        $name_arr = explode('.',$arr_last); //4ebb765a7f49bf09d57644ac2980949a.jpg 分成两部分
        $name = md5($name_arr[0]);
        $ext = $name_arr[1];
        $img_name = $name.'.'.$ext;
        $blur_oss_path = $arr[0].'/'.$arr[1].'/'.$img_name;
        $blurFactor = 7;
        ini_set("memory_limit", "10000M");
//                \think\Image::open($file) 在苹果系统和linux系统找不到临时文件。不知道是什么问题。
//            debugres($base_path);
        $image = \think\Image::open($base_path);
        $image_width = $image->width();
        $image_height = $image->height();

        if($image_width*$image_height<250000){
            $blurFactor = 4;
        }else if($image_width*$image_height>250000 && $image_width*$image_height<1000000){
            $blurFactor = 5;
        }else if($image_width*$image_height>1000000 && $image_width*$image_height<25000000){
            $blurFactor = 6;
        }else{
            $blurFactor = 7;
        }
        //生成模糊图片。
        $blur_base_path = $img->gaussian_blur($base_path,null,$img_name,$blurFactor);
        $info['blur_path'] = './'.$blur_oss_path;
        \service\util\File::oss_upload($blur_oss_path,$blur_base_path,$module);
        return $info['blur_path'];
    }

    /**
     * 文件上传
     * 前端请求地址: http://www.xxx.com/FileUpload?module=demo&type=image(POST表单里传files)
     * 视频前端请求地址: http://www.xxx.com/FileUpload?module=Video&type=video(POST表单里传files)
     * 也可跨模块调用
     * @param $module string 模块名，对应保存路径
     * @param $type string 上传类型，如image、doc，见\extend\util\File
     * @param $show_info bool 是否显示详情信息(用于跨模块调用，传true)
     * @param $cat = false   是否是base64弃用。
     * @param $blur = false  模糊（设计购中的封面裁剪，才会用到）
     * @param $thumb = false  缩略图（设计购中的作品详情图片压缩） 20190708
     * @return array|Response
     */
    public function upload($module, $type, $show_info = false, $cat = false, $blur = false, $thumb = false) {
        if ($cat == true){  //裁剪
            $res = $this->uploadBase64($module, $blur);
            return $res;
        }else{
            if(isset($_FILES["file"])) $_FILES["files"] = $_FILES["file"];
            if($_FILES["files"]["type"] == 'video/mp4') {
                if($_FILES["files"]["size"] > 1024*1024*50) {
                    return api_error('视频不能大于50M');
                }
            }elseif (strlen((string)strpos($_FILES['files']['type'],'image')) >= 1) {
                if($_FILES["files"]["size"] > 1024*1024*8) {
                    return api_error('图片不能大于8M');
                }
            }

            //图片尺寸限制
            if($_FILES && (strlen((string)strpos($_FILES['files']['type'],'image')) >= 1)){
                if($_FILES['files']['error'] == 0){
                    $image_size = getimagesize($_FILES['files']['tmp_name']);
                    //$image_size[0]宽度、$image_size[1]高度
                    if($image_size){
                    }
                }else{
                    return api_error('图片上传失败啦');
                }

            }
            // $module必须是文件上传路径配置好的，否则非法请求
            $paths = config('upload.file_upload_path');
            if (!array_key_exists($module, $paths))
                return api_error('非法请求1');

            // $type必须是文件上传规定类型存在的，否则非法请求
//        print_r(\my\util\File::VALIDATE_TYPE);die;
            if (NULL === \service\util\File::VALIDATE_TYPE[$type])
                return api_error('非法请求2');

            $files = request()->file('files');


//        $files = $_FILES;

            if (NULL === $files)
                return api_error('非法请求3');
            $info = \service\util\File::upload($files,$paths[$module],\service\util\File::VALIDATE_TYPE[$type],$module,$blur,$thumb);
            if ($show_info){
                return json($info);
            }
            else {
                $all_success = true;
                $msg = '';
                foreach ($info as $i) {
                    if(!$i['is_success']) {
                        $all_success = false;
                        $msg .= ('文件'.$i['original_name'].'上传失败,错误信息:'.$i['error_msg'].';');
                    }
                }
                if ($all_success)
                    return api_success('上传成功');
                else
                    return api_error(substr($msg,0,strlen($msg)-1));
            }
        }



    }
}